package com.litidea.actions;

import static com.litidea.commons.keys.MailKeys.REQUEST_ID;
import static com.litidea.commons.keys.SystemKeys.REPORT_UPLOAD_URL;
import static com.litidea.commons.keys.SystemKeys.ATTACHMENTS_UPLOAD_URL;
import static com.litidea.commons.paramkeys.BasicDataParamKeys.SAVE_TEST_ITEMS_PARAMS;

import java.io.File;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.struts2.ServletActionContext;
import org.springframework.mail.javamail.JavaMailSender;

import com.litidea.commons.config.BaseConfig;
import com.litidea.commons.keys.SystemKeys;
import com.litidea.commons.utils.DateTimeUtils;
import com.litidea.commons.utils.MailUtils;
import com.litidea.dao.SystemDAO;
import com.litidea.dataobjects.DepartmentDO;
import com.litidea.dataobjects.RoleDO;
import com.litidea.dataobjects.UserDO;
import com.litidea.dataobjects.UserLoginDO;
import com.opensymphony.xwork2.ActionSupport;

public class BaseAction extends ActionSupport {

	/**
	 * 序列码
	 */
	private static final long serialVersionUID = 8358855557622718107L;
	
	protected JavaMailSender mailSender;

	protected SystemDAO systemDAO;

	// 上传的文件
	protected File image;

	// 上传文件的名称
	protected String imageFileName;

	// 上传文件类型
	protected String imageContentType;

	public SystemDAO getSystemDAO() {
		return systemDAO;
	}

	public void setSystemDAO(SystemDAO systemDAO) {
		this.systemDAO = systemDAO;
	}

	protected final static String SPLITER = "#spliter#";

	protected String[] splitBySpliter(String str) {
		return str.split(SPLITER);
	}

	protected String[] splitBySpliter(String str, String spliter) {
		return str.split(spliter);
	}

	/**
	 * 存储错误信息，用于输出
	 */
	protected String errorInfo;

	public String getErrorInfo() {
		return errorInfo;
	}

	public void setErrorInfo(String errorInfo) {
		this.errorInfo = errorInfo;
	}

	/**
	 * 向前端输出一个JSON格式的数据信息
	 */
	protected String responseAjax(List<? extends Object> list) {
		return responseAjax(createJSONArray(list));
	}

	/**
	 * 创建JSON对象
	 * 
	 * @param list
	 * @return
	 */
	protected String createJSONArray(List<? extends Object> list) {
		if (list == null) {
			return SystemKeys.DEFAULT_JSONARRAY_STR;
		} else {
			JSONArray array = JSONArray.fromObject(list);
			return array.toString();
		}
	}

	/**
	 * 输出一个Ajax
	 * 
	 * @param map
	 * @return
	 */
	protected String responseAjax(Map<? extends Object, ? extends Object> map) {
		return responseAjax(createJSONObject(map));
	}

	/**
	 * 创建一个JSON对象
	 * 
	 * @param map
	 * @return
	 */
	protected String createJSONObject(
			Map<? extends Object, ? extends Object> map) {
		if (map == null) {
			return SystemKeys.DEFAULT_JSONOBJECT_STR;
		}
		return JSONObject.fromObject(map).toString();
	}

	/**
	 * 向前端输出一个字符串
	 * 
	 * @param info
	 * @return
	 */
	protected String responseAjax(String info) {
		try {
			return responseByte(info
					.getBytes(SystemKeys.SYSTEM_DEFAULT_CHARSET));
		} catch (Exception e) {
			return null;
		}
	}

	/**
	 * 向前端输出一个byte[]数组格式的数据
	 * 
	 * @param bytes
	 * @return
	 */
	protected String responseByte(byte[] bytes) {
		try {
			HttpServletResponse response = ServletActionContext.getResponse();
			response.setContentType(SystemKeys.SYSTEM_DEFAULT_CONTENT);
			ServletOutputStream out = response.getOutputStream();
			out.write(bytes);
			out.flush();
		} catch (Exception e) {
		}
		return null;
	}

	/**
	 * 不指定类型输出可能的格式
	 * 
	 * @param object
	 * @return
	 */
	protected String responseAjaxObj(Object object) {
		if (object == null)
			return responseByte(new byte[0]);
		if (object instanceof JSONObject || object instanceof JSONArray)
			return responseAjax(object.toString());
		if (object instanceof String)
			return responseAjax((String) object);
		if (object instanceof List)
			return responseAjax((List<?>) object);
		if (object instanceof Map)
			return responseAjax((Map<?, ?>) object);
		return responseAjax(JSONObject.fromObject(object).toString());
	}

	public Integer getInt(String key) {
		String value = ServletActionContext.getRequest().getParameter(key);
		return StringUtils.isEmpty(value) ? -1 : Integer.valueOf(value);
	}

	public Integer getInt(String key, Integer i) {
		String value = ServletActionContext.getRequest().getParameter(key);
		return StringUtils.isEmpty(value) ? i : Integer.valueOf(value);
	}

	public Long getLong(String key) {
		return Long.getLong(key, -1);
	}

	public Long getLong(String key, Long d) {
		String value = ServletActionContext.getRequest().getParameter(key);
		return value == null ? d : Long.valueOf(value);
	}

	public String getString(String key) {
		return getString(key, null);
	}

	public String[] getStrings(String key) {
		return ServletActionContext.getRequest().getParameterValues(key);
	}

	public String getString(String key, String def) {
		String value = ServletActionContext.getRequest().getParameter(key);
		return value == null ? def : value;
	}

	public String getDateStr(String key) {
		String date = ServletActionContext.getRequest().getParameter(key);
		if (StringUtils.isNotEmpty(date)) {
			return DateTimeUtils.getDateTime(new Date(Long.valueOf(date)),
					DateTimeUtils.DEFAULT_DATE_FORMAT);
		}
		return null;
	}

	/**
	 * 获取参数列表
	 * 
	 * @param paramNames
	 * @param dateNames
	 * @return
	 */
	protected Map<String, String> getParameters(String[] paramNames,
			String[] dateNames) {
		Map<String, String> params = getParameters(getRequest(), paramNames);
		for (String dateName : dateNames) {
			String date = params.get(dateName);
			if (StringUtils.isNotEmpty(date) && date != null) {
				params.put(dateName, DateTimeUtils.getDateTime(new Date(Long
						.valueOf(date)), DateTimeUtils.DEFAULT_DATE_FORMAT));
			}
		}
		return params;
	}

	/**
	 * 获取参数列表
	 * 
	 * @param request
	 * @param paramNames
	 * @return
	 */
	protected Map<String, String> getParameters(HttpServletRequest request,
			String[] paramNames) {
		Map<String, String> map = new HashMap<String, String>(
				paramNames.length * 4 / 3 + 10);
		putRequestUserInfo(map);
		for (String key : paramNames) {
			String value = request.getParameter(key);
			map.put(key, value == null ? null : value.trim());
		}
		return map;
	}

	/**
	 * 向request Map对象中设置用户信息
	 * 
	 * @param map
	 */
	protected void putRequestUserInfo(Map<String, String> map) {
		UserLoginDO userLoginInfo = this.findUserInfo();
		if (userLoginInfo != null) {
			map.put("userId", String.valueOf(userLoginInfo.getId()));
			map.put("userName", userLoginInfo.getName());
			map.put("deptId", String.valueOf(userLoginInfo.getDeptId()));
		}
	}

	/**
	 * 填充用户的一些信息
	 * 
	 * @param map
	 */
	@SuppressWarnings( { "unchecked" })
	protected void putRequestUserInfoAddRoles(Map map) {
		putRequestUserInfo(map);
		UserLoginDO userDO = this.findUserInfo();
		String userId = String.valueOf(userDO.getId());
		List<RoleDO> list = systemDAO.getUserRoles(userId);
		map.put("userRoles", joinUserRoles(list));
		map.put("professional", userDO.getProfessional());
	}

	/**
	 * 一个常规的response输出
	 * 
	 * @param errorInfo
	 * @param trueAlt
	 * @return
	 */
	protected String normalResponse(String errorInfo, String trueAlt) {
		JSONObject obj = new JSONObject();
		if (errorInfo == null) {
			obj.put("status", "1");
			obj.put("msg", trueAlt == null ? "" : trueAlt);
		} else {
			obj.put("status", "0");
			obj.put("msg", errorInfo);
		}
		return responseAjax(obj.toString());
	}

	/**
	 * 获取参数列表
	 * 
	 * @param paramNames
	 * @return
	 */
	protected Map<String, String> getParameters(String[] paramNames) {
		return getParameters(getRequest(), paramNames);
	}

	/**
	 * 获取request对象
	 * 
	 * @return
	 */
	public HttpServletRequest getRequest() {
		return ServletActionContext.getRequest();
	}

	/**
	 * 获取response
	 * 
	 * @return
	 */
	public HttpServletResponse getResponse() {
		return ServletActionContext.getResponse();
	}

	public String getLoginUserId() {
		UserLoginDO userLoginDO = this.findUserInfo();
		return String.valueOf(userLoginDO.getId());
	}

	public String getUserName() {
		UserLoginDO userLoginDO = this.findUserInfo();
		return userLoginDO.getName();
	}

	public String getUserDeptName() {
		UserLoginDO userLoginDO = this.findUserInfo();
		return userLoginDO.getDeptName();
	}
	
	public Integer getUserDeptId() {
		UserLoginDO userLoginDO = this.findUserInfo();
		return userLoginDO.getDeptId();
	}

	public String getUserProfessional() {
		UserLoginDO userLoginDO = this.findUserInfo();
		return userLoginDO.getProfessional();
	}

	/**
	 * 获取用户信息
	 * 
	 * @return
	 */
	protected UserLoginDO findUserInfo() {
		return (UserLoginDO) ServletActionContext.getRequest().getAttribute(
				SystemKeys.USER_LOGIN_DO);
	}

	/**
	 * 合并用户的多个角色
	 * 
	 * @param list
	 * @return
	 */
	protected String joinUserRoles(List<RoleDO> list) {
		StringBuilder buf = new StringBuilder(128);
		for (RoleDO role : list) {
			buf.append(role.getId()).append(",");
		}
		return buf.toString();
	}

	/**
	 * 填充分页列表
	 * 
	 * @param map
	 */
	protected void fillPageParams(Map<String, String> map) {
		if (map == null)
			map = new HashMap<String, String>(4);
		map.put("startRow", getString("start", "0"));
		map.put("limit", getString("limit", "10"));
	}

	/**
	 * 获取JS的版本号码
	 * 
	 * @return
	 */
	public String getJsVersion() {
		return BaseConfig.getString("JS_VERSION");
	}

	/**
	 * 获取验证规则表上传路径
	 * 
	 * @return
	 */
	protected String getVerificationUploadURL() {
		return BaseConfig.getString(ATTACHMENTS_UPLOAD_URL);
	}

	/**
	 * 获取报告上传路径
	 * 
	 * @return
	 */
	protected String getReportUploadURL() {
		return BaseConfig.getString(REPORT_UPLOAD_URL);
	}

	/**
	 * 返回文件全路径
	 * 
	 * @return
	 * @throws Exception
	 */
	protected String saveUploadFile(String type) throws Exception {
		if (image != null) {
			
			// 判断上传路径
			String basePath;
			if(type.equals(ATTACHMENTS_UPLOAD_URL))basePath = this.getVerificationUploadURL();
			else basePath = this.getReportUploadURL();
			
			// 检查文件类型,允许上传zip,rar和PDF格式的文件
			if ("application/pdf".equals(imageContentType)||"application/octet-stream".equals(imageContentType)) {
				// 按时间戳生成文件名
				String saveFileFullName = basePath + "/"
						+ DateTimeUtils.getDateTime("yyyyMMddHHmmss");
				int lastIndex = this.imageFileName.lastIndexOf(".");
				String suffix = imageFileName.substring(lastIndex)
						.toLowerCase();
				File savefile = new File(saveFileFullName + suffix);
				if (!savefile.getParentFile().exists())
					savefile.getParentFile().mkdirs();
				FileUtils.copyFile(image, savefile);
				return saveFileFullName + suffix;
			} else {
				throw new RuntimeException("文件格式不支持");
			}
		} else {
			throw new RuntimeException("文件不能为空");
		}
	}
	
	/**
	 * 查看文档
	 * 
	 * @return
	 */
	public String viewDocument() {
		try {
			HttpServletResponse response = ServletActionContext.getResponse();
			Map<String, String> params = getParameters(SAVE_TEST_ITEMS_PARAMS);
			String docUrl = params.get("docUrl");
			String fileName = docUrl.substring(docUrl.lastIndexOf("/")+1);
			com.litidea.commons.utils.FileUtils.responseFile(response, docUrl, fileName, "true");
		} catch (Exception e) {
			// e.printStackTrace();
		}
		return null;
	}

	/**
     * 获取产业线的部门ID
     * @param deptId
     * @return
     */
    protected DepartmentDO getProductLineDept(String deptId){
		DepartmentDO deptDO = this.systemDAO.getDepartMentById(deptId);
		while(!deptDO.getDeptType().equals("PROD_LINE")){
			if(deptDO.getDeptType().equals("HEAD")) return null;
			deptDO = getProductLineDept(deptDO.getParentId().toString());
		}
		return deptDO;
	}
    
    /**
	 * 邮件提醒
	 * 
	 * @param changeId
	 * @param userId
	 * @param mailSubject
	 * @param mailText
	 */
	protected void emailNotification(String changeId, String userId,
			String mailSubject, String mailText) {
		UserDO appliedUserDO = this.systemDAO.getUserByUserId(userId);
		String applierEmail = appliedUserDO.getEmail();

		MailUtils.sendMail(mailSender, applierEmail, mailSubject.replaceAll(REQUEST_ID, changeId), mailText);
	}

	public File getImage() {
		return image;
	}

	public void setImage(File image) {
		this.image = image;
	}

	public String getImageFileName() {
		return imageFileName;
	}

	public void setImageFileName(String imageFileName) {
		this.imageFileName = imageFileName;
	}

	public String getImageContentType() {
		return imageContentType;
	}

	public void setImageContentType(String imageContentType) {
		this.imageContentType = imageContentType;
	}

	public JavaMailSender getMailSender() {
		return mailSender;
	}

	public void setMailSender(JavaMailSender mailSender) {
		this.mailSender = mailSender;
	}
}
